# -*- coding: utf-8 -*-
import asyncio
import os
import sqlite3
import ast
import botpy
from botpy import logging
from botpy.ext.cog_yaml import read
from botpy.message import DirectMessage , Message
from botpy.ext.cog_yaml import read
import requests
import json
import re
from webdav3.client import Client

qqbot_appid="xxx"
qqbot_token="xxxxxx"
#默认上传路径是我的坚果云，如需要更改请搜索替换
#必须先在频道中@机器人绑定webdav

def bind_webdav(userid, words):
    if len(words) > 1:
        if re.match(r'[\w.-]+@[\w.-]+\.\w+', words[1]):
            webdav_url = 'https://dav.jianguoyun.com/dav/'  
            username = words[1]
            webdav_password = words[2]

        elif re.match(r'https?://[^\s]+$', words[1]):
            webdav_url = words[1]
            username = words[2]  
            webdav_password = words[3]

        else:
              return '绑定格式不正确'

    else:
        return '参数不足'

    # 连接数据库
    try:
        conn = sqlite3.connect('bot.db')
        curs = conn.cursor()

        # 准备数据
        data = {
        'userid': userid,
        'webdav_url': webdav_url,
        'username': username,
        'webdav_password': webdav_password
        }
        curs.execute("CREATE TABLE IF NOT EXISTS qq_bot_users (id INTEGER PRIMARY KEY, webdav_url TEXT, username TEXT, webdav_password TEXT)")
        # 插入或更新数据   
        sql = """INSERT OR REPLACE INTO qq_bot_users (id, webdav_url, username, webdav_password) 
               VALUES (:userid, :webdav_url, :username, :webdav_password)"""

        curs.execute(sql, data)

        # 提交事务
        conn.commit()
        
    finally:

        # 关闭连接
        conn.close()
    return '绑定成功'


def get_webdav_options(userid):
    try:

        # 连接数据库
        conn = sqlite3.connect('bot.db')
        curs = conn.cursor()

        # 查询语句
        sql = "SELECT webdav_url, username, webdav_password FROM qq_bot_users WHERE id=?"  

        # 执行查询
        curs.execute(sql, (userid,))
        result = curs.fetchone()
    except Exception as e:
        print(f"no user")
        return None
    finally:

        # 关闭连接
        conn.close()

    # 处理结果
    if result:
        webdav_url, username, password = result
        return {
          'webdav_hostname': webdav_url,
          'webdav_login': username,  
          'disable_check': True,
          'webdav_password': password
        }
    else:
        return None


        
def upload_webdav(file_name,webdav_options):

    client = Client(webdav_options)
    client.upload(remote_path='/我的坚果云/'+file_name, local_path = file_name)
    
    os.remove(file_name)
    return  True




def download_file_from_ipfs(gateway, file_hash, file_name):
    url = f'{gateway}{file_hash}'

    try:
        response = requests.get(url, timeout=10)
    except Exception as e:
        print(f"Timeout occurred while downloading from {url}")
        return None
    

    if response.status_code == 200:
        with open(file_name, 'wb') as f:
            f.write(response.content)
            return file_name
    else:
        return None
def download_file_from_gateway(file_hash, file_name):




    ipfs_gateways = ['https://ipfs.io/ipfs/', 'https://gateway.ipfs.io/ipfs/',  'https://hardbin.com/ipfs/', 'https://cloudflare-ipfs.com/ipfs/']

    for gateway in ipfs_gateways:
        file_path = download_file_from_ipfs(gateway, file_hash, file_name)
        if file_path:
            break
    if  file_path:
        return  True
    else :
        return False

def save_to_sqlite(id, value):
    # 创建一个数据库连接
    conn = sqlite3.connect('bot.db')

    # 创建一个游标
    curs = conn.cursor()

    # 创建一个字典，以 ID 作为键，字符串作为值
    data = {id: value}
    try:

        # 将字典保存到数据库中
        curs.execute("CREATE TABLE IF NOT EXISTS qq_bot (id INTEGER PRIMARY KEY, value TEXT)")
        for key, value in data.items():
            curs.execute("REPLACE  INTO qq_bot (id, value) VALUES (?, ?)", (key, value))

        # 提交更改
        conn.commit()

        # 关闭游标和连接
        curs.close()
    finally:

        conn.close()
def sort_nested_list(data):
    def sort_key(item):
        return (item['extension'] != 'epub', item['extension'] != 'mobi', -item['filesize'])

    return sorted(data, key=sort_key)
    
def get_string_by_id(userid,get_int,MODE = 'A'):
    # 打开数据库连接
    conn = sqlite3.connect('bot.db')

    # 创建一个游标
    cursor = conn.cursor()
    try:
        # 执行查询语句
        cursor.execute("SELECT value FROM qq_bot WHERE id = ?;", (userid,))

        # 获取查询结果
        result = cursor.fetchone()

        # 关闭游标和连接
        cursor.close()
    finally:

        conn.close()
    str_content = '下载失败，尝试下载同名文件'

    # 如果结果不为空，则读取字符串内容
    if result:
        result = ast.literal_eval(result[0])
        if result[int(get_int)-1]:               
            temp_r = result[int(get_int)-1]
            file_hash = temp_r['ipfs_cid']
            file_name = temp_r['title']+'.'+temp_r['extension']
            if MODE == 'B':
                results = [book for book in result if book['title'] == temp_r['title']]
                results = sort_nested_list(results)
                for i in results:
                    file_name = i['title']+'.'+i['extension']
                    if download_file_from_gateway(i['ipfs_cid'],file_name):
                        break
                webdav_options = get_webdav_options(userid)
                if not webdav_options:
                    return  '请先绑定，在频道中发送  绑定 坚果云账户 对应webdav密码'

                        
                if upload_webdav(file_name,webdav_options):
                    return  '推送完成'
                        
                return  '下载失败'
                        
            elif download_file_from_gateway(file_hash,file_name):
                webdav_options = get_webdav_options(userid)
                if not webdav_options:
                    str_content =  '请先绑定，在频道中发送  绑定 坚果云账户 对应webdav密码'
                else:
                    if upload_webdav(file_name,webdav_options):
                        str_content =  '推送完成'
    return str_content
    
def remove_chars(text):
    # 使用正则表达式匹配英文字母、符号和数字
    pattern = r'[a-zA-Z0-9!@#$%^&*()_+{}\[\]:;<>,.?~\\/-]'
    # 使用re.sub函数将匹配到的字符替换为空字符串
    cleaned_text = re.sub(pattern, '', text)
    return cleaned_text
def remove_domains(text):
    # 正则表达式匹配域名
    domain_pattern = r'\b(?:[a-z0-9]+(?:-[a-z0-9]+)*\.)+[a-z]{2,}\b'
    return re.sub(domain_pattern, '', text)

def get_book(userid,kword):
    kword = kword.strip()
    #https://zlib.knat.network/
    #https://zlib.pseudoyu.com/
    #https://books.cycxtit.eu.org/
    url = "https://zlib.knat.network/search?limit=100&query=title:%22"+kword+"%22"
    if re.match(r'^\d{13}$', kword) :
        url = "https://zlib.knat.network/search?limit=40&query=isbn:%22"+kword+"%22"
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"
    }
    
    response = requests.get(url, headers=headers)

    if response.status_code != 200:
        return '接口错误'
    else:
        books = json.loads(response.text)['books']
        return_str=  ''
        n = 0
                
        if books:
            books_all = [i for i in books if i['extension'] != 'azw3']

            books = books_all[:40]
            for i  in books :
                publisher = ''
                n = n+1
                title = i['title']+'_'+i['extension']+'\t'
                author = i['author']+'\t'
                filesize =  str(round(i['filesize']/1024/1024,2))+'MB'+'\n'

                if i['publisher'] and '出版社' in i['publisher']  :
                    publisher = remove_chars(i['publisher'])+'\t'
                return_str= return_str+ str(n)+'\t'+title+publisher+author+filesize
            return_str = return_str.replace("微信", "")
            return_str = remove_domains(return_str)
            save_to_sqlite(userid, str(books_all))
        else:
            return_str = '没有收录该书籍'

    return return_str
    
def book_qqbot_core(userid,kword,MODE='A'):

    kword = kword.strip()

    kword = re.sub('\s+', ' ', kword) 
    match = re.search(r'<@!\d+>(.+)', kword)
    words = kword.split(' ')
    if match:
        kword = match.group(1)
        kword = kword.strip()
        words = kword.split(' ')
    if MODE=='B':


        return_str = get_string_by_id(userid,kword,'B')
        return return_str
    if words[0] == '绑定':
        return_str = bind_webdav(userid, words)
    else:
        try:
            int_value = int(kword)
            if len(kword)>12 :
                return_str = get_book(userid,kword)
            elif 0<int_value < 41 :
                return_str =  get_string_by_id(userid,kword)
            else :
                return_str ='下载请输入1-50数字'
        except ValueError:
            # 转换失败时执行其他操作
            return_str = get_book(userid,kword)
    
            return return_str
        
    return return_str
_log = logging.get_logger()

    



class MyClient(botpy.Client):
    async def on_ready(self):
        _log.info(f"robot 「{self.robot.name}」 on_ready!")
        
    async def on_at_message_create(self, message: Message):
        _log.info(message.author.avatar)
        if "sleep" in message.content:
            await asyncio.sleep(10)
        _log.info(message.author.username)
        return_content = book_qqbot_core(message.author.id,message.content)


        await message.reply(content=return_content)
        if return_content == '下载失败，尝试下载同名文件' :
            return_content = book_qqbot_core(message.author.id,message.content,'B')
            await message.reply(content=return_content)

        
    async def on_direct_message_create(self, message: DirectMessage):
        return_content = book_qqbot_core(message.author.id,message.content)
        await self.api.post_dms(
            guild_id=message.guild_id,
            content=return_content,
            msg_id=message.id,
        )
        if return_content == '下载失败，尝试下载同名文件' :
            return_content = book_qqbot_core(message.author.id,message.content,'B')
            await self.api.post_dms(
                guild_id=message.guild_id,
                content=return_content,
                msg_id=message.id,
            )   

            
if __name__ == "__main__":

    intents = botpy.Intents(public_guild_messages=True,direct_message=True)
    client = MyClient(intents=intents)
    client.run(appid=qqbot_appid, token=qqbot_token)